﻿//#define SHOW_MAPSCRIPT_BUILD_EXCEPTIONS
//#define SHOW_IMPORT_FILES_EXCEPTIONS
//#define SHOW_CANNOT_CREATE_BACKUP_EXCEPTIONS
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using Moonlite.Data.Mpq;
using Moonlite.ExtensionApi;
using Moonlite.ExtensionApi.ControlInterfaces;
using Moonlite.ExtensionApi.GlobalInterfaces;
using Moonlite.Platform.General;
using Moonlite.Platform.Project;

namespace Moonlite.Compiling
{
    public static class CompilerManager
    {
        private const string StartMapHeaderString = @"//===========================================================================";
        private const string WorldEditorSignatureString = @"//   Warcraft III map script
//   Generated by the Warcraft III World Editor";
        private const string WorldEditorSignatureLine1String = @"//   Warcraft III map script";
        private const string WorldEditorSignatureLine2String = @"//   Generated by the Warcraft III World Editor";
        private const string TriggersString = @"//***************************************************************************
//*
//*  Triggers
//*
//***************************************************************************";
        private const string CustomScriptString = @"//***************************************************************************
//*
//*  Custom Script Code
//*
//***************************************************************************";
        private const string GlobalsSignatureString = @"//***************************************************************************
//*
//*  Global Variables
//*
//***************************************************************************";
        private const string StartSectionSignatureString = @"//***************************************************************************
//*";
        private const string EndSectionSignatureString = @"//*
//***************************************************************************";

        public static event EventHandler Compiled;
        public static CompilerCollection Compilers { get; private set; }
        internal static Process CurrentJassHelperProcess { get; set; }
        internal static List<Process> CurrentRunningJassCompilers { get; set; }
        private static bool JassCompiling { get; set; }
        private static bool GalaxyCompiling { get; set; }
        public static bool AreAnyJassCompilersRunning()
        {
            bool running = false;
            foreach (Process compiler in CurrentRunningJassCompilers)
            {
                if (compiler == null || compiler.HasExited != false)
                    continue;

                running = true;
                break;
            }

            return running;
        }

        public static Process GetFirstUnfinisedJassCompiler()
        {
            foreach (Process compiler in CurrentRunningJassCompilers)
            {
                if (compiler != null && compiler.HasExited == false)
                {
                    return compiler;
                }
            }

            return null;
        }

        public static List<Process> GetUnfinishedJassCompilers()
        {
            List<Process> unfinishedCompilers = new List<Process>();
            CurrentRunningJassCompilers.ForEach(compiler =>
            {
                if (compiler != null && compiler.HasExited == false)
                    unfinishedCompilers.Add(compiler);
            });

            return unfinishedCompilers;
        }

        public static bool IsJassHelperRunning()
        {
            return CurrentJassHelperProcess != null && CurrentJassHelperProcess.SynchronizingObject != null && CurrentJassHelperProcess.HasExited == false;
        }

        private static string ValidateFileContent(string input)
        {
            return input;
        }

        private static string GetWc3MapHeader(string mapScript)
        {
            try
            {
                bool shouldContinue = true;
                int startMapHeaderStringIndex = -1;
                int worldEditorSignatureStringIndex = -1;
                while (shouldContinue == true)
                {
                    startMapHeaderStringIndex = mapScript.IndexOf(StartMapHeaderString);
                    worldEditorSignatureStringIndex = mapScript.IndexOf(WorldEditorSignatureString);
                    if (startMapHeaderStringIndex > -1 && worldEditorSignatureStringIndex > -1)
                    {
                        int currentLineIndex = 0;
                        bool firstLineOK = false;
                        string textFromStart = mapScript.Substring(startMapHeaderStringIndex);
                        foreach (string line in textFromStart.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
                        {
                            if (currentLineIndex == 4)
                            {
                                if (line == WorldEditorSignatureLine1String)
                                {
                                    firstLineOK = true;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else if (currentLineIndex == 5)
                            {
                                if (firstLineOK == true && line == WorldEditorSignatureLine2String)
                                {
                                    shouldContinue = false;
                                    mapScript = textFromStart;
                                    break;
                                }
                                else
                                {
                                    break;
                                }
                            }

                            currentLineIndex++;
                        }

                        if (shouldContinue == true)
                        {
                            mapScript = textFromStart.Substring(StartMapHeaderString.Length);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            catch
            {
                return "";
            }

            return mapScript;
        }

        private static string AddWc3ReferencesToMapScript(string mapScript, IProject project)
        {
            if (project.References.Count > 0)
            {
                DirectoryInfo info = new DirectoryInfo(project.GetReferencesFolderPath());
                if (info.GetFiles("." + Global.CompiledLibraryExtension).Length > 0)
                {
                    foreach (FileInfo fileInfo in info.GetFiles("." + Global.CompiledLibraryExtension))
                    {
                        CompiledLibrary library = LibraryManager.Instance.ReadLibrary(fileInfo.FullName);
                        if (string.IsNullOrEmpty(library.Path) == true || library.Files.Count == 0) continue;
                        IProject referenceProject = ProjectSerializer.LoadProject(library.Path);
                        if (referenceProject != null) AddWc3ReferencesToMapScript(mapScript, referenceProject);
                        foreach (string fileContent in library.Files)
                        {
                            mapScript = fileContent + Environment.NewLine + mapScript;
                        }
                    }
                }
            }

            return mapScript;
        }

        public static bool BuildWc3MapScript(ProjectFileCollection files, string mapPath, IProject project, bool fromCli)
        {
            try
            {
                DirectoryHelper.CreatePath(mapPath);
                if (File.Exists(mapPath) == false)
                {
                    File.Copy(String.Format("{0}\\{1}", Application.StartupPath, project.GetDefaultMapPath()), mapPath);
                }

                if (DirectoryHelper.IsFileReadOnly(mapPath) == true)
                {
                    if (fromCli == false)
                    {
                        MessageBox.Show("An error occurred while compiling the project. The map is being used by another process.");
                    }

                    return false;
                }

                using (TMPQArchive archive = new TMPQArchive(mapPath))
                {
                    string war3mapPath = project.GetTempFolderPath() + "\\war3map.j";
                    DirectoryHelper.CreatePath(war3mapPath);
                    archive.ExportFile("war3map.j", war3mapPath);
                    Stream stream = File.Open(war3mapPath, FileMode.Open);
                    string text = "";
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        text = reader.ReadToEnd();
                    }

                    string mapHeader = GetWc3MapHeader(text);
                    text = text.IndexOf(mapHeader) > -1 ? text.Substring(text.IndexOf(mapHeader)) : text;
                    bool findingEndfunction = false;
                    string excludedText = "";
                    foreach (string line in text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
                    {
                        if (findingEndfunction == true && line.Trim().StartsWith("endfunction") == true)
                        {
                            findingEndfunction = false;
                            continue;
                        }

                        if (findingEndfunction == true)
                        {
                            continue;
                        }

                        if (line.Trim().StartsWith("function jasshelper__initstruct") == true)
                        {
                            findingEndfunction = true;
                            continue;
                        }

                        if (line.Trim().StartsWith("//! import") == false && line.Trim().StartsWith("// BEGIN IMPORT OF") == false &&
                            line.Trim().StartsWith("// END IMPORT OF") == false && string.IsNullOrEmpty(line.Trim(' ', '\r', '\n')) == false &&
                            line.Trim().StartsWith("call ExecuteFunc(") == false)
                        {
                            excludedText += line + Environment.NewLine;
                        }
                    }

                    text = excludedText;
                    int customScriptCodeIndex = text.IndexOf(CustomScriptString);
                    int triggersIndex = text.IndexOf(TriggersString);
                    if (triggersIndex == -1 && customScriptCodeIndex > -1)
                    {
                        int sectionIndex = text.IndexOf(StartSectionSignatureString, customScriptCodeIndex + CustomScriptString.Length);
                        if (sectionIndex > -1)
                        {
                            string header = text.Substring(0, sectionIndex);
                            string footer = text.Substring(sectionIndex);
                            text = header + Environment.NewLine + TriggersString + Environment.NewLine + footer;
                            triggersIndex = text.IndexOf(TriggersString);
                        }
                    }
                    else if (triggersIndex == -1 && customScriptCodeIndex == -1)
                    {
                        int globalsIndex = text.IndexOf(GlobalsSignatureString);
                        if (globalsIndex > -1)
                        {
                            string header = text.Substring(0, globalsIndex);
                            string footer = text.Substring(globalsIndex);
                            text = header + Environment.NewLine + CustomScriptString + Environment.NewLine + TriggersString + Environment.NewLine + footer;
                            triggersIndex = text.IndexOf(TriggersString);
                            customScriptCodeIndex = text.IndexOf(CustomScriptString);
                        }
                        else
                        {
                            int startSectionIndex = text.IndexOf(StartSectionSignatureString);
                            if (startSectionIndex > -1)
                            {
                                int endSectionIndex = text.IndexOf(EndSectionSignatureString, startSectionIndex);
                                if (endSectionIndex > -1)
                                {
                                    string header = text.Substring(0, endSectionIndex + EndSectionSignatureString.Length);
                                    string footer = text.Substring(endSectionIndex + EndSectionSignatureString.Length);
                                    text = header + Environment.NewLine + CustomScriptString + Environment.NewLine + TriggersString + Environment.NewLine + footer;
                                    triggersIndex = text.IndexOf(TriggersString);
                                    customScriptCodeIndex = text.IndexOf(CustomScriptString);
                                }
                                else
                                {
                                    ShowError("Cannot read malformed map script. Map is corrupt.");
                                }
                            }
                            else
                            {
                                ShowError("Cannot read malformed map script. Map is corrupt.");
                            }
                        }
                    }

                    if (triggersIndex > -1)
                    {
                        string header = "";
                        if (customScriptCodeIndex > -1)
                        {
                            header = text.Substring(0, customScriptCodeIndex);
                            text = text.Substring(triggersIndex);
                        }
                        else
                        {
                            header = text.Substring(0, triggersIndex);
                            text = text.Substring(triggersIndex);
                        }

                        text = AddWc3ReferencesToMapScript(text, project);
                        foreach (ProjectFile file in files)
                        {
                            if (File.Exists(file.Path) == true && Path.GetExtension(file.Path) == Global.JassFileExtension && file.BuildAction == ProjectFileCompileType.Compile)
                            {
                                string validatedContent = "";
                                using (StreamReader reader = new StreamReader(file.Path)) validatedContent = ValidateFileContent(reader.ReadToEnd());
                                using (StreamWriter writer = new StreamWriter(file.Path, false)) writer.Write(validatedContent);
                                text = validatedContent + Environment.NewLine + text;
                            }
                        }

                        text = CustomScriptString + Environment.NewLine + text;
                        text = header + text;
                        text = text.Substring(0, text.LastIndexOf("endfunction") + "endfunction".Length);
                        int commentIndex = text.IndexOf("//Struct method generated initializers/callers:");
                        if (commentIndex > -1)
                        {
                            text = text.Substring(0, commentIndex);
                        }

                        stream.Close();
                        stream = File.Open(war3mapPath, FileMode.Create);
                        using (StreamWriter writer = new StreamWriter(stream))
                        {
                            writer.Write(text);
                        }

                        archive.ImportFile("war3map.j", war3mapPath);
                        stream.Close();
                        archive.Close();
                    }
                    else
                    {
                        stream.Close();
                    }
                }
            }
            catch (ObjectDisposedException exception)
            {
                Logger.Log += exception.Message + Environment.NewLine;
#if (DEBUG && SHOW_MAPSCRIPT_BUILD_EXCEPTIONS)
                throw exception;
#endif
            }
            catch (IOException exception)
            {
                Logger.Log += exception.Message + Environment.NewLine;
#if (DEBUG && SHOW_MAPSCRIPT_BUILD_EXCEPTIONS)
                throw exception;
#endif
            }

            return true;
        }

        private static bool ImportFiles(ProjectFileCollection files, string mapPath, IProject project)
        {
            try
            {
                DirectoryHelper.CreatePath(mapPath);
                if (File.Exists(mapPath) == false)
                {
                    File.Copy(String.Format("{0}\\{1}", Application.StartupPath, project.GetDefaultMapPath()), mapPath);
                }

                if (DirectoryHelper.IsFileReadOnly(mapPath) == true)
                {
                    MessageBox.Show("An error occurred while importing files. The map is being used by another process.");
                    return false;
                }

                using (TMPQArchive archive = new TMPQArchive(mapPath))
                {
                    foreach (ProjectFile file in files)
                    {
                        if (file.BuildAction == ProjectFileCompileType.Import && !string.IsNullOrEmpty(file.ImportPath))
                        {
                            try
                            {
                                archive.ImportFile(file.ImportPath, file.Path);
                            }
                            catch (Exception exception)
                            {
                                Logger.Log += exception.Message + Environment.NewLine;
                                MessageBox.Show("Error importing file: " + exception.Message);
                            }
                        }
                    }
                }
            }
            catch (IOException exception)
            {
                Logger.Log += exception.Message + Environment.NewLine;
#if (DEBUG && SHOW_IMPORT_FILES_EXCEPTIONS)
                throw exception;
#endif
            }

            return true;
        }

        private static bool CreateBackup(string mapPath, string backupMapPath)
        {
            try
            {
                if (File.Exists(mapPath) == true)
                {
                    if (File.Exists(backupMapPath) == true)
                    {
                        File.Delete(backupMapPath);
                    }

                    File.Copy(mapPath, backupMapPath);
                    return true;
                }
            }
            catch (Exception exception)
            {
                Logger.Log += exception.Message;
#if (DEBUG && SHOW_CANNOT_CREATE_BACKUP_EXCEPTIONS)
                    ShowError(String.Format("An error occured while making backup of map:{0}{1}", Environment.NewLine, exception.Message));
#endif
            }

            return false;
        }

        public static bool ExecuteWc3(IProject project)
        {
            if (project == null || project.Type != ProjectType.Jass)
            {
                return false;
            }

            if (JassCompiling == true) return false;
            if (IsJassHelperRunning() == true) CurrentJassHelperProcess.WaitForExit();
            if (AreAnyJassCompilersRunning() == true) GetUnfinishedJassCompilers().ForEach(compiler => compiler.WaitForExit());
            CurrentRunningJassCompilers.Clear();
            bool compiled = true;
            ProjectFileCollection files = project.GetAllFiles();
            string mapPath = project.GetMapPath();
            DirectoryHelper.CreatePath(mapPath);
            string backupMapPath = String.Format("{0}\\{1}_backup{2}", project.GetTempFolderPath(), Path.GetFileName(mapPath), Path.GetExtension(mapPath));
            CreateBackup(mapPath, backupMapPath);
            JassCompiling = true;
            if (BuildWc3MapScript(files, mapPath, project, false) == true)
            {
                foreach (ICompiler compiler in Compilers)
                {
                    if (compiler.Type == CompilerType.Jass)
                    {
                        string newMapPath = String.Format("{0}\\{1}", Path.GetDirectoryName(compiler.GetRealExePath()), Path.GetFileName(mapPath));
                        if (File.Exists(newMapPath) == true)
                        {
                            File.Delete(newMapPath);
                        }

                        try
                        {
                            File.Copy(mapPath, newMapPath);
                            int exitCode = compiler.Compile(newMapPath);
                            if (compiler.Name.ToLower() == "jasshelper")
                            {
                                CurrentJassHelperProcess = compiler.InnerProcess;
                            }
                            else
                            {
                                CurrentRunningJassCompilers.Add(compiler.InnerProcess);
                            }

                            if (exitCode != 0)
                            {
                                compiled = false;
                            }

                            if (File.Exists(mapPath) == true)
                            {
                                File.Delete(mapPath);
                            }

                            File.Copy(newMapPath, mapPath);
                        }
                        catch (Exception exception)
                        {
                            Logger.Log += exception.Message + Environment.NewLine;
                            try
                            {
                                File.Delete(mapPath);
                                File.Copy(backupMapPath, mapPath);
                            }
                            catch (Exception innerException)
                            {
                                Logger.Log += innerException.Message;
                            }

                            if (exception is IOException)
                            {
                                ShowError(String.Format("An error occured why compiling the project:{0}{1}", Environment.NewLine, exception.Message));
                            }
                        }
                    }
                }

                ImportFiles(files, mapPath, project);
            }
            else
            {
                compiled = false;
            }

            JassCompiling = false;
            if (compiled)
            {
                if (Compiled != null)
                {
                    Compiled(null, EventArgs.Empty);
                }
            }

            return compiled;
        }

        public static bool ExecuteWc3()
        {
            return ExecuteWc3(Global.Instance.Project);
        }

        public static bool ExecuteAndromeda(IProject project, bool hidden, bool waitForExit, bool importFiles, bool useTempMapPath, string extraArguments)
        {
            const int Timeout = 30000;
            if (project == null || project.Type != ProjectType.Galaxy || GalaxyCompiling == true)
            {
                return false;
            }

            bool compiled = true;
            ProjectFileCollection files = project.GetAllFiles();
            string mapPath = project.GetMapPath();
            DirectoryHelper.CreatePath(mapPath);
            if (File.Exists(mapPath) == false)
            {
                File.Copy(String.Format("{0}\\{1}", Application.StartupPath, project.GetDefaultMapPath()), mapPath);
            }

            if (DirectoryHelper.IsFileReadOnly(mapPath) == true)
            {
                if (hidden == false) ShowError("An error occurred while compiling the project. The map is being used by another process.");
                return false;
            }

            string backupMapPath = String.Format("{0}\\{1}_backup{2}", project.GetTempFolderPath(), Path.GetFileNameWithoutExtension(mapPath), Path.GetExtension(mapPath));
            CreateBackup(mapPath, backupMapPath);
            if (useTempMapPath) mapPath = backupMapPath;
            DirectoryHelper.CreatePath(mapPath);
            DirectoryHelper.CreateFolderPath(Global.GetAndromedaOutputFolderPath());
            if (!hidden) GalaxyCompiling = true;
            foreach (ICompiler compiler in Compilers)
            {
                if (compiler.Name.ToLower() == "andromeda")
                {
                    if (!useTempMapPath)
                    {
                        AndromedaOutputStream.Instance.ClearMessages();
                    }
                    try
                    {
                        using (Process compilerProcess = new Process())
                        {
                            string arguments = " -jar \"" + compiler.GetRealExePath() + "\" -i\"" + mapPath + "\" -o\"" + mapPath + "\" -s\"" + Global.GetAndromedaOutputFolderPath() + "\\" + Global.AndromedaObjectsFileName + "\" -e\"" + Global.GetAndromedaOutputFolderPath() + "\\" + Global.AndromedaErrorsFileName + "\" ";
                            foreach (ProjectFile file in files)
                            {
                                file.UpdateBuildAction();
                                if (File.Exists(file.Path) == true && file.BuildAction == ProjectFileCompileType.Compile)
                                {
                                    string filePath = file.Path;
                                    bool fileOpen = false;
                                    ITextEditor foundEditor = null;
                                    foreach (ITextEditor editor in Global.Instance.TextEditors)
                                    {
                                        if ((editor.File != null && editor.File.Path == filePath) || editor.InnerTextEditor.FileName == filePath)
                                        {
                                            fileOpen = true;
                                            foundEditor = editor;
                                            break;
                                        }
                                    }
                                    if (fileOpen)
                                    {
                                        string newFilePath = Global.GetTempFolderPath() + "\\" + Path.GetFileName(filePath);
                                        try
                                        {
                                            if (File.Exists(newFilePath))
                                            {
                                                File.Delete(newFilePath);
                                            }
                                            File.Copy(filePath, newFilePath);
                                            using (StreamWriter writer = new StreamWriter(newFilePath))
                                            {
                                                writer.Write("//DSCFormat:Path=" + filePath + ";Project=" + project.Name + ";" + Environment.NewLine + foundEditor.InnerTextEditor.Text);
                                            }
                                            filePath = newFilePath;
                                        }
                                        catch (Exception exception)
                                        {
                                            Logger.Log += exception.Message + Environment.NewLine;
                                        }
                                    }
                                    string validatedContent = "";
                                    using (StreamReader reader = new StreamReader(filePath)) validatedContent = ValidateFileContent(reader.ReadToEnd());
                                    using (StreamWriter writer = new StreamWriter(filePath, false)) writer.Write(validatedContent);
                                    arguments += "\"" + filePath + "\" ";
                                }
                            }

                            compilerProcess.StartInfo = new ProcessStartInfo("java", arguments) { UseShellExecute = false, WorkingDirectory = Path.GetDirectoryName(compiler.GetRealExePath()) };
                            compilerProcess.StartInfo.WindowStyle = hidden == true ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal;
                            compilerProcess.StartInfo.CreateNoWindow = hidden;
                            compilerProcess.StartInfo.RedirectStandardOutput = true;
                            compilerProcess.StartInfo.RedirectStandardError = true;
                            compilerProcess.StartInfo.RedirectStandardInput = true;
                            compilerProcess.Start();
                            if (waitForExit == true)
                            {
                                compilerProcess.WaitForExit(Timeout);
                                if (!useTempMapPath)
                                {
                                    AndromedaOutputStream.Instance.Text = compilerProcess.StandardOutput.ReadToEnd() + compilerProcess.StandardError.ReadToEnd();
                                }
                                compiled = compilerProcess.ExitCode > -1;
                                if (compiled)
                                {
                                    if (Compiled != null)
                                    {
                                        Compiled(null, EventArgs.Empty);
                                    }
                                }
                            }
                        }
                    }
                    catch (IOException exception)
                    {
                        Logger.Log += exception.Message + Environment.NewLine;
                        if (hidden == false) ShowError("An error occurred while compiling the project: " + exception.Message);
                        compiled = false;
                    }
                }
            }

            if (importFiles) ImportFiles(files, mapPath, project);
            if (!hidden) GalaxyCompiling = false;
            return compiled;
        }

        public static bool ExecuteAndromeda()
        {
            return ExecuteAndromeda(Global.Instance.Project, true, true, true, false, "");
        }

        public static bool ExecuteCLIAndromeda(IProject project)
        {
            return ExecuteAndromeda(project, true, false, false, true, " --nocode");
        }

        public static bool ExecuteCLIAndromeda()
        {
            return ExecuteCLIAndromeda(Global.Instance.Project);
        }

        public static void ExecuteCLIJassHelper()
        {
            ExecuteCLIJassHelper(Global.Instance.Project);
        }

        public static void ExecuteCLIJassHelper(IProject project)
        {
            if (project.Type == ProjectType.Jass)
            {
                if (JassCompiling == true)
                {
                    return;
                }

                if (IsJassHelperRunning() == true)
                {
                    CurrentJassHelperProcess.WaitForExit();
                }

                ProjectFileCollection files = project.GetAllFiles();
                string mapPath = String.Format("{0}\\{1}\\{2}", project.GetTempFolderPath(), Global.ObjFolderName, Path.GetFileName(project.GetMapPath()));
                DirectoryHelper.CreatePath(mapPath);
                string w3xMapPath = String.Format("{0}\\{1}.w3x", Path.GetDirectoryName(mapPath), Path.GetFileNameWithoutExtension(mapPath));
                if (BuildWc3MapScript(files, w3xMapPath, project, true) == true)
                {
                    foreach (ICompiler compiler in Compilers)
                    {
                        if (compiler.Name.ToLower() == "jasshelper")
                        {
                            string newMapPath = String.Format("{0}\\{1}", Path.GetDirectoryName(compiler.GetRealExePath()), Path.GetFileName(w3xMapPath));
                            if (DirectoryHelper.IsFileReadOnly(newMapPath) == true)
                            {
                                return;
                            }

                            try
                            {
                                if (File.Exists(newMapPath) == true)
                                {
                                    File.Delete(newMapPath);
                                }

                                File.Copy(w3xMapPath, newMapPath);
                                using (Process compilerProcess = new Process())
                                {
                                    string arguments = compiler.DefaultCLIArgs;
                                    string realExePath = Path.GetDirectoryName(compiler.GetRealExePath()) + "\\clijasshelper.exe";
                                    if (arguments == "common.j Blizzard.j")
                                    {
                                        arguments = String.Format("\"{0}\\common.j\" \"{0}\\Blizzard.j\"", Path.GetDirectoryName(realExePath));
                                    }

                                    ProcessStartInfo info = new ProcessStartInfo(realExePath, arguments + (compiler.AddPathToMap == true ?
                                        String.Format(" \"{0}\"", w3xMapPath) : "")) { WindowStyle = ProcessWindowStyle.Hidden };

                                    compilerProcess.StartInfo = info;
                                    compilerProcess.Start();
                                    CurrentJassHelperProcess = compilerProcess;
                                }
                            }
                            catch (Exception exception)
                            {
                                Logger.Log += exception.Message + Environment.NewLine;
                            }

                            if (DirectoryHelper.IsFileReadOnly(w3xMapPath) == true)
                            {
                                return;
                            }

                            try
                            {
                                if (File.Exists(w3xMapPath) == true)
                                {
                                    File.Delete(w3xMapPath);
                                }

                                File.Copy(newMapPath, w3xMapPath);
                            }
                            catch (Exception exception)
                            {
                                Logger.Log += exception.Message + Environment.NewLine;
                            }
                        }
                    }
                }
            }
        }

        public static void LoadCompilers()
        {
            Compilers = CompilerReader.Load();
        }

        private static void ShowError(string message)
        {
            MessageBox.Show(message, "Moonlite Map Studio", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
        }

        static CompilerManager()
        {
            CurrentRunningJassCompilers = new List<Process>();
        }
    }
}
